package com.kara.woodAgent.agent.wood.node;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.kara.woodAgent.agent.graph.Next;
import com.kara.woodAgent.agent.graph.Node;
import com.kara.woodAgent.agent.model.ModelProvider;
import com.kara.woodAgent.agent.tool.provider.ToolProvider;
import com.kara.woodAgent.agent.wood.context.WoodReactContext;
import com.kara.woodAgent.agent.wood.model.ExpectedMessage;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.data.message.AiMessage;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.chat.request.ChatRequest;
import dev.langchain4j.model.chat.response.ChatResponse;

import java.util.List;
import java.util.Map;

/**
 * @author tzy
 * @version 1.0
 * @project wood_agent
 * @description
 * @date 2025/6/11 12:21:51
 */
public class ThinkNode implements Node<WoodReactContext> {

    private final ModelProvider modelProvider;

    private final ToolProvider.ToolServiceHolder toolProviderHolder;


    public ThinkNode(ModelProvider modelProvider, ToolProvider.ToolServiceHolder toolProviderHolder) {
        this.modelProvider = modelProvider;
        this.toolProviderHolder = toolProviderHolder;
    }

    @Override
    public Next execute(WoodReactContext context) {

        List<ChatMessage> chatMessages = context.getChatMessages();
        ChatLanguageModel chatModel = modelProvider.getChatModel();


        AiMessage aiMessage;
        //不同意执行
        ExpectedMessage expectedMessage = context.getExpectedMessage();
        String disAgreeMsg = expectedMessage.getDisAgreeMsg();
        if (StrUtil.isNotBlank(disAgreeMsg)) {
            AiMessage last = (AiMessage) chatMessages.getLast();
            AiMessage from;
            if(StrUtil.isNotBlank(last.text())){
                from = AiMessage.from(last.text());
            }else {
                List<ToolExecutionRequest> toolExecutionRequests = last.toolExecutionRequests();
                from = AiMessage.from(toolExecutionRequests.toString());
            }
            chatMessages.removeLast();
            chatMessages.add(from);
//			String disAgreeMsg = expectedMessage.getDisAgreeMsg();
            UserMessage userMessage = UserMessage.from("不同意你之前的工具调用，原因是： " + disAgreeMsg + "\n" +
                    "请你重新思考分析下一步要做什么,你应该考虑以下问题:" +
                    " 1. 您需要创建或完善计划吗？\n" +
                    " 2. 您准备好执行特定步骤了吗？\n" +
                    " 3. 你完成了任务吗？\n" +
                    "  提供推理，然后选择适当的工具工作。\n" +
                    "  *** 强制要求 *** 当你完成所有任务之后，你必须调用exit工具，并且告知我你已经完成了所有任务。\n"+
                    "  *** 强制要求 *** 你必须调用一个合适的工具"
            );
            chatMessages.add(userMessage);
            ChatRequest request = ChatRequest.builder()
                    .toolSpecifications(toolProviderHolder.toolSpecifications())
//                    .responseFormat(ResponseFormat.builder().type(ResponseFormatType.JSON).build())
                    .messages(chatMessages).build();
            ChatResponse chatResponse = chatModel.chat(request);
            aiMessage = chatResponse.aiMessage();

//            //将最后的 aiMessage 和 不同意移除掉
//            chatMessages.removeLast();
//            chatMessages.removeLast();
//
//            //移除将最后的 aiMessage
//            expectedMessage.getExpectedWindows().removeLast();
        } else {
            UserMessage userMessage = UserMessage.from("""
                                #### 注意
                    			请你根据当前的执行情况你,分析下一步要做什么,你应该考虑以下问题:
                                    1. 您需要创建或完善计划吗？
                                    2. 您准备好执行特定步骤了吗？
                                    3. 你完成了任务吗？
                                提供推理，然后选择适当的工具工作。
                                *** 强制要求 *** 当你完成所有任务之后，你必须调用exit工具，并且告知我你已经完成了所有任务。
                                *** 强制要求 *** 你必须调用一个合适的工具
                    """);
            chatMessages.add(userMessage);
            expectedMessage.getExpectedWindows().add(userMessage);
            ChatRequest request = ChatRequest.builder()
                    .toolSpecifications(toolProviderHolder.toolSpecifications())
//                    .responseFormat(ResponseFormat.builder().type(ResponseFormatType.JSON).build())
                    .messages(chatMessages).build();
            ChatResponse chatResponse = chatModel.chat(request);
            aiMessage = chatResponse.aiMessage();

        }

        expectedMessage.setDisAgreeMsg(null);

        //陷入 think-review 的阈值
        int i = context.addLoopCount();
        //i>3 强制 人工干预
        if (aiMessage.hasToolExecutionRequests() && i < 3) {
            chatMessages.add(aiMessage);
            expectedMessage.getExpectedWindows().add(aiMessage);
            context.setExpectedMessage(expectedMessage);
            return Next.NextNode("review").step(aiMessage.toString());
        } else {
            ToolExecutionRequest.Builder tool = ToolExecutionRequest.builder().id("consume_" + System.currentTimeMillis())
                    .name("interrupt")
                    .arguments(JSON.toJSONString(Map.of("message", aiMessage.text())));
            ToolExecutionRequest build = tool.build();
            AiMessage from = AiMessage.from(aiMessage.text(), List.of(build));
            chatMessages.add(from);
            expectedMessage.getExpectedWindows().add(from);
            context.setToolExecutionRequest(List.of(build));
            context.setExpectedMessage(expectedMessage);
            return Next.NextNode("tool").step("no_tool exit:  " + aiMessage.toString());
        }
    }
}
